#include "DataTransportConfig.hh"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>


#include "TSystem.h"
#include "TApplication.h"
#include "TCanvas.h"
#include <TH2F.h>
#include <TF1.h>
#include <TF2.h>
#include <TStyle.h>

DataTransportConfig *DataTrnsportRead;
TCanvas *c2;
TH2F *hlego2[7];

char *Buffer;
unsigned int datalength;

unsigned int data[3500];
unsigned char NumOfDetector;
unsigned int NumOfData;
unsigned int NumOfLengt;
unsigned int MIMOSA_DatalenTmp;
int datalengthAll = 0;
int r = 0;
int t = 0;

unsigned int Header0;
unsigned int Header1;
unsigned int MIMOSA_Counter0;
unsigned int MIMOSA_Counter1;
unsigned int MIMOSA_Datalen0;
unsigned int MIMOSA_Datalen1;
unsigned int MIMOSA_Datalen;
unsigned int MIMOSA_Trailer0;
unsigned int MIMOSA_Trailer1;
unsigned int StatusLine;
unsigned int OVF;
unsigned int NumOfState;
unsigned int AddLine;
unsigned int State;
unsigned int AddColum;
unsigned int HitPix;

static void *thread_func(void *vptr_args)
{
	while(1){
		t++;
		datalength = DataTrnsportRead->ReadDataTransportSocket_length("priv");
		Buffer = DataTrnsportRead->ReadDataTransportSocket_data(datalength);
		/*
		 *
		 *  D A T A    U N C O M P R E S S
		 *
		 */

		for (int i = 0; i < 3500; i++)
			data[i] = 0;
		int i = 0;
		int k = 0;
		NumOfData = 0;
		while (i < datalength) {
			data[k] = 0xFF & Buffer[i + 1];
			data[k] <<= 8;
			data[k] += 0xFF & Buffer[i];
			//printf("w=0x%x ", data[k] );
			i = i + 2;
			k++;
		}
		//printf(" \n" );
		while (1) {
			if (NumOfData > ((datalength / 2) - 2))
				break;
			Header0 = data[NumOfData++];
			Header1 = data[NumOfData++];

			if ((Header0 == 0x5555) & (Header1 == 0x5551))		{ NumOfDetector = 1; NumOfData++; NumOfData++;}
			if ((Header0 == 0x5555) & (Header1 == 0x5552))		NumOfDetector = 2;
			if ((Header0 == 0x5555) & (Header1 == 0x5553))		NumOfDetector = 3;
			if ((Header0 == 0x5555) & (Header1 == 0x5554))		NumOfDetector = 4;
			if ((Header0 == 0x5555) & (Header1 == 0x5555))		NumOfDetector = 5;
			if ((Header0 == 0x5555) & (Header1 == 0x5556))		NumOfDetector = 6;
			MIMOSA_Counter0 = data[NumOfData++];
			MIMOSA_Counter1 = data[NumOfData++];
			MIMOSA_Datalen0 = data[NumOfData++];
			MIMOSA_Datalen1 = data[NumOfData++];
			MIMOSA_Datalen = MIMOSA_Datalen0 + MIMOSA_Datalen1;
			//printf("Header0=%x  ", Header0);
			//printf("Header1=%x  ", Header1);
			//printf("MIMOSA_Counter0=%x  ", MIMOSA_Counter0);
			//printf("MIMOSA_Counter1=%x  ", MIMOSA_Counter1);
			//printf("MIMOSA_Datalen0=%x  ", MIMOSA_Datalen0);
			//printf("MIMOSA_Datalen1=%x  \n", MIMOSA_Datalen1);
			//printf(" \n", Header1);
			/*
			 *
			 * R E A D   S T A T U S
			 *
			 */

			NumOfLengt = 0;
			MIMOSA_DatalenTmp = NumOfData + MIMOSA_Datalen;
			while (1) {
				if (NumOfData > ((datalength / 2) - 2))
					break;
				if (NumOfData >= MIMOSA_DatalenTmp)
					break;
				StatusLine = data[NumOfData++];
				OVF = StatusLine >> 15;
				NumOfState = StatusLine & 0xF;
				AddLine = (StatusLine >> 4) & 0x7FF;
				//printf("OVF=%d ", OVF);
				//printf("AddLine=%d ", AddLine);
				//printf("NumOfState=%d  \n", NumOfState);
				/*
				 * R E A D   S T A T E
				 */
				//*

				for (int k = 0; k < NumOfState; k++) {
					if (NumOfData > ((datalength / 2) - 2))
						break;
					if (NumOfData >= MIMOSA_DatalenTmp)
						break;
					State = data[NumOfData++];
					AddColum = (State >> 2) & 0x7FF;
					HitPix = State & 0x3;
					//printf("                              AddColum=%d ", AddColum);
					//printf("HitPix=%d \n", HitPix);
					for (Int_t i = 0; i <= HitPix; i++) {
						hlego2[NumOfDetector]->Fill(AddColum, AddLine + i);
					}
				}
			}
			MIMOSA_Trailer0 = data[NumOfData++];
			MIMOSA_Trailer1 = data[NumOfData++];
			//printf("Tr0=%x   ", MIMOSA_Trailer0);
			//printf("Tr1=%x \n", MIMOSA_Trailer1);

		}
		//printf("NumOfData = %d  \n", NumOfData );
		//printf("t = %d \n", t);
		if (t == 8680) {
			r++;
			printf("r = %d \n", r);
			//printf(" Data=%d ", datalengthAll);
			datalengthAll = 0;
			t = 0;
			for (int NumDetector = 1; NumDetector< 7; NumDetector++) hlego2[NumDetector]->Reset();
			for (int NumDetector = 1; NumDetector< 7; NumDetector++) {
				c2->cd(NumDetector);
				gStyle->SetPalette(1);
				hlego2[NumDetector]->Draw("COLZs");
			}
			c2->Update();
		}
		datalength = 0;
	//Read2();
	return NULL;
	}
}


int main(int argc, char *argv[]) {


	TApplication mainApp("mainApp", &argc, argv);
	pthread_t thread;

	c2 = new TCanvas("c2", "c2", 1000, 800);
	c2->Divide(3, 2);

	hlego2[1] = new TH2F("=1=", "chip# 11", 550, 0, 1152, 270, 0, 576);
	hlego2[2] = new TH2F("=2=", "chip# 12", 550, 0, 1152, 270, 0, 576);
	hlego2[3] = new TH2F("=3=", "chip# 19", 550, 0, 1152, 270, 0, 576);
	hlego2[4] = new TH2F("=4=", "chip# 4", 550, 0, 1152, 270, 0, 576);
	hlego2[5] = new TH2F("=5=", "chip# 2", 550, 0, 1152, 270, 0, 576);
	hlego2[6] = new TH2F("=6=", "chip# 20", 550, 0, 1152, 270, 0, 576);
	for (int i = 1; i < 7; i++) {
		c2->cd(i);
		gStyle->SetPalette(1);
		hlego2[i]->Draw("COLZ");
	}

	DataTrnsportRead = new DataTransportConfig;
	DataTrnsportRead->ClientDatatransportSocketRun();

	if (pthread_create(&thread, NULL, thread_func, NULL) != 0)	return EXIT_FAILURE;
	mainApp.Run();
	if (pthread_join(thread, NULL) != 0) return EXIT_FAILURE;

	return EXIT_SUCCESS;
}
/*


*/
//	}

